<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Carbon\Carbon;
use DB;

class BaseModel extends Model
{
    const SUCCESS = 20000;
    const FAILURE = 20001;
    protected function serializeDate(\DateTimeInterface $date)
    {
        return Carbon::instance($date)->toDateTimeString();
    }

    // 传递 ID 或 数组ID , 第二参表示以指定字段 为键 , 默认否''
    protected function getListId($id, $str='id')
    {
        if (is_array($id)) {
            $data = $this->whereIn($str, $id)->get()->toArray();
        } else {
            $data = $this->where($str, $id)->get()->toArray();
        }

        if (!empty($data)) {
            $data = key_val($data, $str);
        }

        return $data;
    }
    protected function success($data=[])
    {
        return [
            'data' => $data,
            'code' => 20000
        ];
    }

    protected function error($data, $code = 20001)
    {
        return [
            'data'=>$data,
            'code'=>$code
        ];
    }
    // 用户端 成功返回
    protected function successClient($data=[], $info = '')
    {
        return [
            'info' => $info,
            'data' => $data,
            'code' => 20000
        ];
    }
    // 用户端 失败返回
    protected function errorClient($data, $info = '')
    {
        return [
            'info' => $info,
            'data' => $data,
            'code' => 20001
        ];
    }
    // 用户端 自定义code返回
    protected function backJsonClient($data, $info = '', $code = 20002)
    {
        return [
            'info' => $info,
            'data' => $data,
            'code' => $code
        ];
    }

    protected function successSim($info='操作成功',$data=[]){
        $info = empty($info)?'操作成功':$info;
        $code = self::SUCCESS;
        $retval = $this->buildReturnJson($code,$info,$data);
        return $retval;
    }

    protected function errorSim($info='操作失败',$data=[]){
        $info = empty($info)?'操作失败':$info;
        $code = self::FAILURE;
        $retval = $this->buildReturnJson($code,$info,$data);
        return $retval;
    }
    private function buildReturnJson($code,$info,$data=[]){
        $retval = [];
        $retval['code'] = $code;
        $retval['info'] = $info;
        $retval['data'] = $data;
        return $retval;
    }
    
    // 批量更新
    protected function updateBatch($multipleData = [], $tableName)
    {
        try {
            if (empty($multipleData)) {
                throw new \Exception("数据不能为空");
            }
            // $tableName = DB::getTablePrefix() . $this->getTable(); // 前缀 + 表名
                
            $firstRow  = current($multipleData);//获取第一条数据
                
            $updateColumn = array_keys($firstRow);//获取第一条数据所有键的数组
                
            // 默认以id为条件更新，如果没有ID则以第一个字段为条件
            $referenceColumn = isset($firstRow['id']) ? 'id' : current($updateColumn);//id存在以id为查询条件 ,否则以第一个键为查询条件
            unset($updateColumn[0]);//注销第一个键 ,此时数组只剩下需要更改的数据
                
            // 拼接sql语句
            $updateSql = "UPDATE " . $tableName . " SET ";
            $sets      = [];
            $bindings  = [];
            foreach ($updateColumn as $uColumn) {
                $setSql = "`" . $uColumn . "` = CASE ";
                foreach ($multipleData as $data) {
                    $setSql .= "WHEN `" . $referenceColumn . "` = ? THEN ? ";
                    $bindings[] = $data[$referenceColumn];
                    $bindings[] = $data[$uColumn];
                }
                $setSql .= "ELSE `" . $uColumn . "` END ";
                $sets[] = $setSql;
            }
                
            $updateSql .= implode(', ', $sets);
            $whereIn   = collect($multipleData)->pluck($referenceColumn)->values()->all();
            $bindings  = array_merge($bindings, $whereIn);
            $whereIn   = rtrim(str_repeat('?,', count($whereIn)), ',');
            $updateSql = rtrim($updateSql, ", ") . " WHERE `" . $referenceColumn . "` IN (" . $whereIn . ")";
            // 传入预处理sql语句和对应绑定数据
            // return $updateSql;
            return DB::update($updateSql, $bindings);
        } catch (\Exception $e) {
            return false;
        }
    }
}
